import React, { useState, useImperativeHandle, forwardRef, useRef, useMemo } from 'react';
import { Modal, units } from '@library';
import { ModalProps } from 'antd/lib/modal';
import View from './View';
import { getFormUrlAndQuery } from './../eval';
import { ShowModalOptionsType } from './../interface';

const defaultOptions = {
  width: 1000
};

const bodyStyle = {
  height: '430px',
  display: 'flex',
  flexDirection: 'column' as any,
  overflowY: 'auto' as any,
  padding: 0
};

export interface ModalFormRef {
  show(options: ShowModalOptionsType, changeId?: string): void;
  hide(): void;
}

interface IProps {
  onValuesChange(id: string, data: any): void;
}

export default forwardRef(({ onValuesChange }: IProps, ref: React.Ref<ModalFormRef>) => {
  const isSetFooter = useRef(false);
  const currChagneId = useRef<string | undefined>('');
  const [visible, setVisible] = useState(false);
  const [initValue, setInitValue] = useState({});
  const [modalOptions, setModalOptions] = useState<ModalProps>(defaultOptions);
  const [content, setContent] = useState({ list: [], enviromentConfig: undefined });
  const [footer, setFooter] = useState<React.ReactNode | null>(null);
  const [defaultFull, setDefaultFull] = useState(false);

  useImperativeHandle(ref, () => ({
    hide: onCancel,
    async show(options, changeId) {
      currChagneId.current = changeId;

      const _options = { ...options };
      if (options.initValue) setInitValue(options.initValue);

      if (options.form) {
        const { url, where } = getFormUrlAndQuery(options.form);

        try {
          const res = await units.server(url, { where });

          if (res.content) {
            const content = JSON.parse(res.content);

            _options.title = _options.title || res.formName;

            if (_options.hasDataList) {
              _options.bodyStyle = { ...bodyStyle, ...options.bodyStyle };
            }

            setDefaultFull(options.isFull || false);
            setContent({ list: content?.list, enviromentConfig: res.enviromentConfig ? JSON.parse(res.enviromentConfig) : undefined, });
            setVisible(true);
            setModalOptions({ ...defaultOptions, ..._options });
          }
        } catch (error) {

        }
      }
    }
  }));

  function onCancel() {
    setVisible(false);
    setModalOptions({});
    setInitValue({});
    isSetFooter.current = false;
  }

  function parentNext(data: object) {
    onCancel();

    const copyData: any = { ...data };
    delete copyData._HEAD_;

    onValuesChange(currChagneId.current!, copyData);
  }

  const data = useMemo(() => {
    return { _HEAD_: initValue };
  }, [initValue]);
 
  return (
    <Modal
      destroyOnClose
      defaultFull={defaultFull}
      visible={visible}
      footer={footer}
      onCancel={onCancel}
      {...modalOptions}>
      <View
        data={data}
        structure={content}
        parentNext={parentNext}
        setFooter={obj => {
          if (!isSetFooter.current) {
            setFooter(obj.footer);
            isSetFooter.current = true;
          }
        }}
      />
    </Modal>
  );
});